﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
//
//Description : Classe qui représente un champ éloigné d'un entité
//Auteur : Marc-Eric Boisvert
//Date Création : 31 mars 2008
//Révisions:
//
/// <summary>
/// Classe qui représente un champ éloigné d'un entité
/// </summary>
/// <remarks>
/// Il est très important que la séquence de JOIN soit de la table source vers la table foreign. 
/// Voir l'exemple.
/// </remarks>
/// <exemple>
/// L'exemple suivant montre comment afficher le champ Nom de ta lable fournisseur dans l'entité Commande_Detail.
/// 
/// NOM_FOURNISSEUR
/// Dim f As ForeignFieldMultiTable
/// f = New ForeignFieldMultiTable(Me, GetType(String), "FOURNISSEUR", "NOM", 40, False, GetType(Fournisseur))
/// f.Joins.Add(New JoinInfo(New FieldInfo("GCL", "COMMANDE_DETAIL", "ID_PRODUIT"), New FieldInfo("GCL", "PRODUIT", "ID_PRODUIT")))
/// f.Joins.Add(New JoinInfo(New FieldInfo("GCL", "PRODUIT", "ID_FOURNISSEUR"), New FieldInfo("GCL", "FOURNISSEUR", "ID_FOURNISSEUR")))
/// f.Name = "NOM_FOURNISSEUR"
/// f.ListColumnName = "COMMANDE_DETAIL.NOM_FOURNISSEUR"
/// Me.AddField("NOM_FOURNISSEUR", f)
/// </exemple>
/// 
namespace Framework.Data.Core
{
    [Serializable()]
    public class ForeignFieldMultiTable : EntityField, IForeignFieldMultiTable
    {

        #region "Membres"
        //Utiliser pour affiché des combobox dans les listes d'éditions
        protected Type _foreignEntityType;
        #endregion
        protected List<JoinInfo> _joins = new List<JoinInfo>();

        #region "Constructeurs"

        /// <summary>
        /// Constructeur
        /// </summary>
        /// <param name="entity">L'entité à qui appartient le champ</param>
        /// <param name="fieldValueType">Type du champ</param>
        /// <param name="tableName">Nom de la table du champ</param>
        /// <param name="databaseFieldName">Nom du champ bd</param>
        /// <param name="fieldSize">Longueur du champ</param>
        /// <param name="isPrimaryKey">est-ce une clé primaire</param>
        /// <remarks></remarks>
        public ForeignFieldMultiTable(IBaseEntity entity, Type fieldValueType, string tableName, string databaseFieldName, int fieldSize, bool isPrimaryKey, Type foreignEntityType)
            : base(entity, fieldValueType, tableName.ToUpper(), databaseFieldName.ToUpper(), fieldSize, isPrimaryKey, false)
        {
            this._foreignEntityType = foreignEntityType;
        }

        #endregion

        #region "Propriétés"
        /// <summary>
        /// Contient la liste des liens à faire entre les tables
        /// </summary>
        /// <value>List(Of EntityField)</value>
        /// <returns>List(Of EntityField)</returns>
        /// <remarks></remarks>
        public List<JoinInfo> Joins
        {
            get { return this._joins; }
        }

        /// <summary>
        /// Type de l'entité éloigné
        /// </summary>
        /// <value>Type</value>
        /// <returns>Type</returns>
        /// <remarks></remarks>
        public Type ForeignEntityType
        {
            get { return this._foreignEntityType; }
            set { this._foreignEntityType = value; }
        }

        #endregion

        #region "Méthodes"

        /// <summary>
        /// Fonction qui permet d'afficher la valeur du champ éloigné
        /// </summary>
        /// <returns>string</returns>
        /// <remarks></remarks>
        public override string ToString()
        {
            return base.ToString();
        }

        #endregion

    }

    public struct JoinInfo
    {
        public FieldInfo LeftInfo;

        public FieldInfo RightInfo;
        /// <summary>
        /// Constructeur
        /// </summary>
        /// <param name="leftInfo">Partie de gauche du join</param>
        /// <param name="rightInfo">partie de droite du join</param>
        /// <remarks></remarks>
        public JoinInfo(FieldInfo leftInfo, FieldInfo rightInfo)
        {
            this.LeftInfo = leftInfo;
            this.RightInfo = rightInfo;
        }
    }

    public struct FieldInfo
    {
        public string Schema;
        public string TableName;

        public string FieldName;
        /// <summary>
        /// Constructeur
        /// </summary>
        /// <param name="schema">Schema</param>
        /// <param name="tableName">Nom de la table</param>
        /// <param name="fieldName">Nom du champ bd</param>
        /// <remarks></remarks>
        public FieldInfo(string schema, string tableName, string fieldName)
        {
            this.Schema = schema.ToUpper();
            this.TableName = tableName.ToUpper();
            this.FieldName = fieldName.ToUpper();
        }
    }
}